home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / utils / dos / cp.c next >
C/C++ Source or Header  |  1995-04-18  |  7KB  |  332 lines

  1.  
  2. /*
  3.  *
  4.  *    Copyright 1993 Algorithms Corporation
  5.  *
  6.  *    ALL RIGHTS RESERVED.
  7.  *
  8.  *
  9.  *
  10.  */
  11.  
  12.  
  13. #include <stdio.h> 
  14. #include <sys/types.h>
  15. #include <sys/stat.h>
  16. #include <fcntl.h>
  17. #include <io.h>
  18. #include <malloc.h>
  19. #include <dos.h>
  20. #include <errno.h>
  21.  
  22.  
  23. static    void    strip_path(), print_error();
  24. static    void    usage();
  25. static    int    copy_file();
  26.  
  27. #define    here    fprintf(stderr, "%s (%d)\n", __FILE__, __LINE__);
  28.  
  29. int    main(argc, argv)
  30. int    argc;
  31. char    *argv[];
  32. {
  33.     int    r, i, isdir, err=0, quiet=0, verbose=0, existing=0, zero=0;
  34.     int    recurse=0;
  35.     char    buf[128], tmp[128];
  36.     
  37.     if (argc < 3)
  38.         usage();
  39.     isdir = isDir(argv[argc-1]);
  40.     argc--;
  41.     for ( ; 1 < argc  &&  argv[1][0] == '-' ; argc--, argv++)
  42.         for (r=1 ; argv[1][r] ; ++r)
  43.             switch (argv[1][r])  {
  44.             case 'e':
  45.             case 'E':
  46.                 existing = 1;
  47.                 break;
  48.             case 'q':
  49.             case 'Q':
  50.                 quiet = 1;
  51.                 verbose = 0;
  52.                 break;
  53.             case 'r':
  54.             case 'R':
  55.                 recurse = 1;
  56.                 break;
  57.             case 'v':
  58.             case 'V':
  59.                 verbose = 1;
  60.                 quiet = 0;
  61.                 break;
  62.             case 'z':
  63.             case 'Z':
  64.                 zero = 1;
  65.                 break;
  66.             default:
  67.                 fprintf(stderr, "cp:  Unknown flag %c\n", argv[1][r]);
  68.                 break;
  69.             }
  70.     if (!isdir  &&  recurse)  {
  71.         if (makeDir(argv[argc]))  {
  72.             fprintf(stderr, "cp:  Can't create directory %s\n", argv[argc]);
  73.             exit(zero ? 0 : 1);
  74.         }
  75.         isdir = 1;
  76.     }
  77.     if (argc > 2  &&  !isdir  ||  argc < 2)
  78.         usage();
  79.     for (i=1 ; i < argc ; ++i)  {
  80.         if (isdir)  {
  81.             if (recurse  &&  isDir(argv[i]))  {
  82.                 if (copy_dir(argv[i], argv[argc], verbose, existing, quiet))
  83.                     err = 1;
  84.             } else {
  85.                 char    c;
  86.  
  87.                 strip_path(tmp, argv[i]);
  88.                 strcpy(buf, argv[argc]);
  89.                 c = buf[strlen(buf)-1];
  90.                 if (c != '/'  &&  c != '\\'  &&  c != ':')
  91.                     strcat(buf, "/");
  92.                 strcat(buf, tmp);
  93.                 r = copy_file(argv[i], buf, verbose, existing);
  94.                 if (r)  {
  95.                     if (!quiet)
  96.                         print_error(r, argv[i], buf);
  97.                     err = 1;
  98.                 }
  99.             }
  100.         }  else  {
  101.             r = copy_file(argv[i], argv[argc], verbose, existing);
  102.             if (r)  {
  103.                 if (!quiet)
  104.                     print_error(r, argv[i], argv[argc]);
  105.                 err = 1;
  106.             }
  107.         }
  108.     }
  109.     return zero ? 0 : err;
  110. }
  111.  
  112. int    copy_dir(fd, td, verbose, existing, quiet)
  113. char    *fd, *td;
  114. int    verbose, existing, quiet;
  115. {
  116.     char    fpath[80], tdir[80], tpath[80];
  117.     int    r, flg, err=0;
  118.     struct    _find_t    fi;
  119.  
  120.     strip_path(fpath, fd);
  121.     if (!strcmp(fpath, ".")  ||  !strcmp(fpath, ".."))
  122.         return 0;
  123.     if (*fpath)
  124.         sprintf(tdir, "%s/%s", td, fpath);
  125.     else
  126.         strcpy(tdir, td);
  127.     if (makeDir(tdir))  {
  128.         if (!quiet)
  129.             print_error(12, NULL, tdir);
  130.         return 12;
  131.     }
  132.  
  133.  
  134.     r = strlen(fd) - 1;
  135.     if (flg = (fd[r] == ':'  ||  fd[r] == '/'  ||  fd[r] == '\\'))
  136.         sprintf(fpath, "%s*.*", fd);
  137.     else
  138.         sprintf(fpath, "%s/*.*", fd);
  139.     r = _dos_findfirst(fpath, (_A_ARCH|_A_HIDDEN|_A_NORMAL|_A_RDONLY|_A_SUBDIR|_A_SYSTEM), &fi);
  140.     while (!r)  {
  141.         if (flg)
  142.             sprintf(fpath, "%s%s", fd, fi.name);
  143.         else
  144.             sprintf(fpath, "%s/%s", fd, fi.name);
  145.         if (isDir(fpath))
  146.             copy_dir(fpath, tdir, verbose, existing, quiet);
  147.         else  {
  148.             sprintf(tpath, "%s/%s", tdir, fi.name);
  149.             r = copy_file(fpath, tpath, verbose, existing);
  150.             if (r)  {
  151.                 if (!quiet)
  152.                     print_error(r, fpath, tpath);
  153.                 err = 1;
  154.             }
  155.         }
  156.         r = _dos_findnext(&fi);
  157.     }
  158.     return err;
  159. }
  160.  
  161. static    void    print_error(r, ff, tf)
  162. int    r;
  163. char    *ff, *tf;
  164. {
  165.     switch (r)  {
  166.     case 1:
  167.         fprintf(stderr, "cp:  source file %s doesn't exist\n", ff);
  168.         break;
  169.     case 2:
  170.         fprintf(stderr, "cp:  can't create %s\n", tf);
  171.         break;
  172.     case 3:
  173.         fprintf(stderr, "cp:  error writing to %s\n", tf);
  174.         break;
  175.     case 4:
  176.         fprintf(stderr, "cp:  error reading %s\n", ff);
  177.         break;
  178.     case 7:
  179.         fprintf(stderr, "cp:  attempt to overwrite existing file %s\n", tf);
  180.         break;
  181.     case 10:
  182.         fprintf(stderr, "cp:  out of memory\n", ff);
  183.         break;
  184.     case 11:
  185.         fprintf(stderr, "cp:  source file %s is a directory\n", ff);
  186.         break;
  187.     case 12:
  188.         fprintf(stderr, "cp:  Can't create directory %s\n", tf);
  189.         break;
  190.     default:
  191.         fprintf(stderr, "cp:  Can't copy %s to %s (error %d)\n", ff, tf, r);
  192.         break;
  193.     }
  194. }
  195.  
  196. static    void    usage()
  197. {
  198.     printf("Usage:\tcp  [-option]  file  file\n"); 
  199.     printf("\tcp  [-option]  file...  directory\n");
  200.     printf("Options:\n");
  201.     printf("\te\tdon't overwrite existing files\n");
  202.     printf("\tq\tquiet (no error messages)\n");
  203.     printf("\tr\trecurse into sub-directories\n");
  204.     printf("\tv\tverbose\n");
  205.     printf("\tz\talways return 0 exit status\n");
  206.     exit(1); 
  207. }
  208.  
  209. static    void    strip_path(to, from)
  210. char    *from, *to;
  211. {
  212.     char    *t;
  213.  
  214.     for (t=from ; *t ; ++t)
  215.         if (*t == '/'  ||  *t == '\\'  ||  *t == ':')
  216.             from = t + 1;
  217.     strcpy(to, from);
  218. }
  219.  
  220. static    int    copy_file(ff, tf, verbose, existing)
  221. char    *ff, *tf;
  222. int    verbose;
  223. int    existing;   /*  don't overwrite existing files  */
  224. {
  225.     int    fh, th, n;
  226.     unsigned    date, time;
  227.     static    char    *buf = NULL;
  228.     static    unsigned    bs = 16384;
  229.     
  230.     if (existing  &&  !access(tf, 0))
  231.         return 7;
  232.  
  233.     if (0 > (fh = open(ff, O_BINARY | O_RDONLY, 0)))
  234.         return isDir(ff) ? 0 : 1;
  235.     
  236.     if (0 > (th = open(tf, O_BINARY | O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE)))  {
  237.         close(fh);
  238.         return(2);
  239.     }
  240.     
  241.     if (!buf)
  242.         while (bs > 127  &&  !(buf = malloc(bs)))
  243.             bs /= 2;
  244.     if (!buf)  {
  245.         close(fh);
  246.         close(th);
  247.         return(10);    /*  out of memory    */
  248.     }
  249.     
  250.     if (verbose)
  251.         printf("Copying %s -> %s\n", ff, tf);
  252.  
  253.     while (0 < (n = read(fh, buf, bs)))
  254.         if (n != write(th, buf, n))  {
  255.             close(fh);
  256.             close(th);
  257.             return(3);    /*  write error      */
  258.         }
  259.  
  260.     if (n)  {
  261.         close(fh);
  262.         close(th);
  263.         return(4);    /*  read error   */
  264.     }
  265.     
  266.     _dos_getftime(fh, &date, &time);
  267.     _dos_setftime(th, date, time);
  268.  
  269.     if (close(fh))  {
  270.         close(th);
  271.         return(5);
  272.     }
  273.     if (close(th))
  274.         return(6);
  275.     return(0);
  276. }
  277.  
  278. int    makeDir(f)
  279. char    *f;
  280. {
  281.     char    path[100], *p;
  282.     struct    stat    sb;
  283.     
  284.     p = path;
  285.     if (*f  &&  f[1] == ':')  {
  286.         *p++ = *f++;
  287.         *p++ = *f++;
  288.     }
  289.     while (*f)  {
  290.         for (*p++ = *f++ ; *f  &&  *f != '/' && *f != '\\' ; )
  291.             *p++ = *f++;
  292.         *p = '\0';
  293.         if (stat(path, &sb))  {  /*  path doesn't exist  */
  294.             if (mkdir(path))
  295.                 return 1;   /*  can't create  */
  296.         } else if (!(sb.st_mode&S_IFDIR))
  297.             return 1;     /*  not a directory  */
  298.     }
  299.     return(0);
  300. }
  301.  
  302. int    isDir(f)
  303. char    *f;
  304. {
  305.     struct    stat    sb;
  306.     char    buf[5];
  307.  
  308.     if (*f  &&  f[1] == ':'  &&  !f[2])  {
  309.         strcpy(buf, f);
  310.         strcat(buf, ".");
  311.         f = buf;
  312.     }
  313.     if (stat(f, &sb))
  314.         return 0;
  315.     return sb.st_mode & S_IFDIR;
  316. }
  317.  
  318.  
  319.  
  320.  
  321. /*
  322.  *
  323.  *    Copyright 1993 Algorithms Corporation
  324.  *
  325.  *    ALL RIGHTS RESERVED.
  326.  *
  327.  *
  328.  *
  329.  */
  330.  
  331.  
  332.